#include "tasks.h"
#include<stdlib.h>


using namespace std;

void TaskCPU(vector<int> params) { // params: n
	uso_CPU(params[0]); // Uso el CPU n milisegundos.
}

void TaskIO(vector<int> params) { // params: ms_cpu, ms_io,
	uso_CPU(params[0]); // Uso el CPU ms_cpu milisegundos.
	uso_IO(params[1]); // Uso IO ms_io milisegundos.
}

void TaskCon(vector<int> params) { // params: ms_cpu, ms_io,
	int n = params[0];
	int bmin = params[1];
	int bmax = params[2];
	srand ( time(NULL) );
	int duracionRnd,i;
	if(bmin == bmax){
		for(i=0;i<n;i++)
		{
			duracionRnd = bmin; 
			uso_IO(duracionRnd); // Uso IO ms_io milisegundos.
		}
	}
	else{
		for(i=0;i<n;i++)
		{
			duracionRnd = (rand()%(bmax-bmin+1))+ bmin; 
			uso_IO(duracionRnd); // Uso IO ms_io milisegundos.
		}
	}

}


void Task_N_InputOuput(vector<int> params) { // params: n
        for( int i = 0; i < params[0] ; i++ ) {
                uso_IO(params[1]); // Uso IO ms_io milisegundos.
        }
	if(params[2] != 0)
		uso_CPU(params[2]); // Uso CPU ms_io milisegundos.
}


void TaskBatch(vector<int> params) { // params: tot, blocks,
	int totalCPU = params[0];
    	int totalBloqueo = params[1];
	srand ( time(NULL) );
	
	//El tiempo total de CPU que utilice la tarea deber ́ ser de tot ciclos de reloj, incluyendo el tiempo
    //utilizado por las llamadas bloqueantes.

    //aca vamos a guardar las posiciones en que se ejectuan los bloqueos en true y false si se ejecuta cpu
	vector<bool> totalEjecucion = vector<bool>(totalCPU  -1);
        
	//por cada bloqueo elijo una posicion al azar
	for(int i=0;i<totalBloqueo ;i++) {
		int posicionBloqueo = rand()%(totalEjecucion.size()-1);
        
        //si no esta ocupada esa posicion la ocupo
		if( !totalEjecucion [posicionBloqueo] )
			totalEjecucion[posicionBloqueo] = true;	
        else
			i--; //como no lo ubique decremento la variable del for
	}
		
	//ejecuto cpu o I/O segun corresponda
   	 for(int i=0;i<(int)totalEjecucion.size();i++) {
		if( totalEjecucion[i] ) 
			uso_IO(1);
		else
			uso_CPU(1);
		
	}
}


void tasks_init(void) {
	/* Todos los tipos de tareas se deben registrar acá para poder ser usadas.
	 * El segundo parámetro indica la cantidad de parámetros que recibe la tarea
	 * como un vector de enteros, o -1 para una cantidad de parámetros variable. */
	register_task(TaskCPU, 1);
	register_task(TaskIO, 2);
	register_task(TaskCon, 3);
	register_task(TaskBatch, 2);
	register_task(Task_N_InputOuput,3);
}
